package com.qf.shiro2302.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.shiro2302.entity.User;
import com.qf.shiro2302.mapper.UserMapper;
import com.qf.shiro2302.roleperm.entity.TPers;
import com.qf.shiro2302.roleperm.entity.TRole;
import com.qf.shiro2302.roleperm.entity.TRolePerms;
import com.qf.shiro2302.roleperm.entity.TUserRole;
import com.qf.shiro2302.roleperm.mapper.TPersMapper;
import com.qf.shiro2302.roleperm.mapper.TRoleMapper;
import com.qf.shiro2302.roleperm.mapper.TRolePermsMapper;
import com.qf.shiro2302.roleperm.mapper.TUserRoleMapper;
import com.qf.shiro2302.service.UserService;
import com.qf.shiro2302.utils.Constants;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {

    @Value("${qf.shiro.hashtimes}")
    private Integer hashtimes;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TUserRoleMapper tUserRoleMapper;

    @Autowired
    private TRoleMapper tRoleMapper;

    @Autowired
    private TRolePermsMapper tRolePermsMapper;

    @Autowired
    private TPersMapper tPersMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void register(String username, String password) throws Exception {

        //1. 查询用户名是否已经存在了
        User dbuser = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));

        if (dbuser!=null){
            throw new Exception("用户名已经存在了，请更换");
        }

        //2. 执行注册逻辑
        //2.1 生成salt
        String salt = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8);
        //2.2 生成密码
        String md5password = new Md5Hash(password, salt, Constants.HASH_TIMES).toHex();
        //2.3 入库
        User user = new User();
        user.setUsername(username);
        user.setPassword(md5password);
        user.setSalt(salt);
        userMapper.insert(user);
    }

    @Override
    public List<String> getRolesFromDB(User user) {

        List<String> result =  userMapper.selectRolesFromDB(user.getId());

        return result;
    }

    @Override
    public List<String> getPermissionsFromDB(User user) {

        List<String> result =  userMapper.selectPermissionsFromDB(user.getId());

        return result;
    }

    @Override
    public List<String> getRolesFromDBbyMp(User user) {

        //1 SELECT roleid FROM t_user_role WHERE userid=2;
        List<Object> roleidList = tUserRoleMapper.selectObjs(new QueryWrapper<TUserRole>().select("roleid").eq("userid", user.getId()));

        //2 SELECT NAME FROM t_role WHERE id IN (1,2);
        List<Object> rolenameList = tRoleMapper.selectObjs(new QueryWrapper<TRole>().select("name").in("id", roleidList));

        //3. List<Object> ----> List<String>
//        ArrayList<String> list = new ArrayList<>();
//        for (Object o : rolenameList) {
//            String s = (String) o;
//            list.add(s);
//        }
        // 使用Stream流实现List中数据类型的转换
        List<String> list = rolenameList.stream().map(o -> (String) o).collect(Collectors.toList());

        return list;
    }

    @Override
    public List<String> getPermissionsFromDBbyMp(User user) {

        // SELECT roleid FROM t_user_role WHERE userid=2;
        List<Object> roleidList = tUserRoleMapper.selectObjs(new QueryWrapper<TUserRole>().select("roleid").eq("userid", user.getId()));

        // SELECT permsid FROM t_role_perms WHERE roleid IN (1,2);
        List<Object> permsidList = tRolePermsMapper.selectObjs(new QueryWrapper<TRolePerms>().select("permsid").in("roleid", roleidList));

        // SELECT NAME FROM t_pers WHERE id IN (1,2,3);
        List<Object> permnameList = tPersMapper.selectObjs(new QueryWrapper<TPers>().select("name").in("id", permsidList));

        // List<Object> ----> List<String>
        List<String> list = permnameList.stream()
                .map(o -> (String) o)
//                .distinct()
                .collect(Collectors.toList());


        return list;
    }
}
